import { fabric } from "fabric";
import useFileStore from "../store/files";
import { History } from "./history";

class FabricCanvas {
  constructor(canvasElement, options = {}, onUpdateLines) {
    this.canvas = new fabric.Canvas(canvasElement, {
      ...options,
      isDrawingMode: false,
      selection: true, // 允许选择对象
      selectionColor: "rgba(64,224,208, 0.2)",
      preserveObjectStacking: true,
    });
    this.lines = []; // 存储所有的线
    this.currentLine = null;
    this.lineCount = 0; // 用来追踪线条的数量
    this.onUpdateLines = onUpdateLines || function () {};
    this.start = false;

    this.canvas.on("mouse:down", (options) => this.handleMouseDown(options));
    this.canvas.on("mouse:move", (options) => this.handleMouseMove(options));
    this.initCanvasStorage();
  }

  initCanvasStorage() {
    const { files, currentId } = useFileStore.getState();
    const file = files?.find((item) => item?.id === currentId);
    console.log("file", file);
    if (file) {
      this.canvas.loadFromJSON(file?.boardData, () => {
        this.canvas.renderAll();
        this.history = new History(this.canvas);
      });
    }
  }

  startDrawing() {
    this.start = true;
    this.currentLine = null; // 确保开始一个新线条
    this.canvas.selection = false; // 绘制时禁止选择其他对象
  }

  finishDrawing() {
    this.start = false;
    this.canvas.selection = true; // 绘制时禁止选择其他对象
  }

  handleMouseDown(options) {
    // 阻止默认右键菜单
    // 右键取消当前点
    if (options.button === 3) {
      options.e.preventDefault();
      options.e.stopPropagation();
      if (this.currentLine) {
        this.canvas.remove(this.currentLine);
        this.currentLine = null;
      } else {
        // 检查是否有选中的对象，并尝试删除
        const activeObject = this.canvas.getActiveObject();
        if (activeObject) {
          this.removeLine(activeObject);
          this.canvas.discardActiveObject();
          this.canvas.requestRenderAll();
        }
      }
      return false;
    }
    if (this.start) {
      const pointer = this.canvas.getPointer(options.e);
      if (!this.currentLine) {
        const points = [pointer.x, pointer.y, pointer.x, pointer.y];
        this.currentLine = new fabric.Line(points, {
          strokeWidth: 2,
          stroke: "aqua",
          strokeDashArray: [3, 3],
          selectable: true,
          originX: "center",
          originY: "center",
          hoverCursor: "pointer",
        });
        this.canvas.add(this.currentLine);
      } else {
        this.currentLine.set({ x2: pointer.x, y2: pointer.y });
        this.lines.push(this.currentLine);
        // 更新父组件的线条
        this.onUpdateLines(this.lines);
        // 在线条上添加序号
        this.addLineNumber(this.currentLine, ++this.lineCount);
        this.history?.saveState();
        this.currentLine = null;
      }
    }
  }

  handleMouseMove(options) {
    if (this.start && this.currentLine) {
      const pointer = this.canvas.getPointer(options.e);
      this.currentLine.set({ x2: pointer.x, y2: pointer.y });
      this.canvas.renderAll();
    }
  }
  //添加文字-序号
  addLineNumber(line, number) {
    const midpoint = line.getCenterPoint();
    const text = new fabric.Text(number.toString(), {
      left: midpoint.x,
      top: midpoint.y - 18, //调整数字位置在线的中心偏上
      fontSize: 18,
      fill: "#ffffff",
      originX: "center",
      originY: "center",
      hoverCursor: "default",
    });
    this.canvas.add(text);
  }
  //移除线条
  removeLine(line) {
    const index = this.lines.indexOf(line);
    if (index > -1) {
      this.lines.splice(index, 1);
    }
    this.onUpdateLines(this.lines);
  }
  //移除选择的线条
  deleteSelectedLine() {
    const activeObject = this.canvas.getActiveObjects();
    if (activeObject) {
      activeObject.forEach((obj) => {
        this.canvas.remove(obj);
        this.removeLine(obj);
      });
      this.canvas.discardActiveObject(); //取消当前选中的对象（或对象组）
      this.render();
    }
  }
  render() {
    if (this.canvas) {
      this.canvas.requestRenderAll();
      this.history?.saveState();
    }
  }
  getCanvasJSON() {
    if (this.canvas) {
      return this.canvas.toDatalessJSON([
        "id",
        "_customType",
        "perPixelTargetFind",
        "objectCaching",
      ]);
    }
  }
  removeCanvas() {
    if (this.canvas) {
      this.canvas.dispose();
      this.canvas = null;
    }
  }
}

export default FabricCanvas;
